Skip to content

FR-132 v2.8: harden the Examples picker for host-supplied corpora - #19

Merged
Evgenus merged 2 commits into
mainfrom
fix-examples-picker-host-corpus
Jul 18, 2026
Merged

FR-132 v2.8: harden the Examples picker for host-supplied corpora#19
Evgenus merged 2 commits into
mainfrom
fix-examples-picker-host-corpus

Conversation

@Evgenus

@Evgenus Evgenus commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

What

Fixes the user-reported regression "examples are duplicated and uncategorised" in the embedded Examples picker. SPEC-first amendment of FR-132 (SPEC v2.7 → v2.8, no new IDs), then the implementation:

  • Label disambiguation — when two entries in the same group would render the same doc-first-sentence label, each is suffixed with " — <case name>". The engine guarantees unique names, not unique doc sentences: the pinned corpus already collides in three rule groups (attr, join, this) even when fully categorised.
  • Graceful degradation — a corpus in which no entry carries tier or rule membership renders as a single flat, ungrouped list. Previously all such entries were shoved under one fabricated "Reference · other" optgroup. Partially categorised corpora keep "Reference · other" for the rule-less tail, unchanged.
  • Embedder seambuildExampleCorpusFromDocs(docs) is split out of buildExampleCorpus and re-exported from @transon/editor-react and @transon/editor-element (with the EditorDocs/EditorMetadata types). It takes the metadata-contract §2.7 docs shape, which is isomorphic to the engine's get_all_docs() payload.

Why

FR-132 (shipped in v0.2.0) derives tier/rule only inside buildExampleCorpus — but a host-supplied host.examples override bypasses that derivation entirely. The docs-site embed (transon-org.github.ioEditorView.tsxtoExampleCases) hand-maps the engine corpus to {name, doc, tags, template, data, result}, dropping the join keys, so its picker rendered all 163 cases in one "Reference · other" group ("uncategorised") with colliding labels covering 13 entries ("duplicated"). The old panels.tsx comment claiming host corpora "flow through the same derivation" was wrong — that comment is fixed too.

Reviewer notes

  • Presentation-only (§21.12): no codec, artifacts, ordering, or round-trip surface is touched. Selection semantics unchanged — the unique case name stays the option value + tooltip (AC-018).
  • Tests were written red-first in examples-picker.test.tsx: flat degradation, mixed-corpus "other" retention, collision suffixing, per-group scoping of disambiguation (the same sentence under two different rules stays bare), and buildExampleCorpusFromDocs/buildExampleCorpus parity. The pre-existing test that asserted the ['Reference · other'] behavior for host corpora was updated to the amended SPEC.
  • The traceability FR-132 row is updated in the same change; all gates green (traceability, engine-parity 23/29/34, snapshot check), full suites pass (editor-ui 206, editor-react 5, editor-element 12).
  • Live-verified in the Pyodide reference host (snapshot and ?metadata=engine&engine=0.2.2 paths): 163 options, 22 groups, 0 duplicate values, 0 remaining within-group label collisions, console clean.
  • Follow-up (separate repo): the docs site should replace toExampleCases with the exported buildExampleCorpusFromDocs once a new editor tarball is released — that's what restores the Worked examples / Recipes / per-rule groups in its embedded picker.

Refs: FR-132, FR-009

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Improved the Examples picker: disambiguates duplicate example description labels within each group and gracefully degrades to a flat list when no tier/rule membership exists.
    • Added public helper buildExampleCorpusFromDocs for building example corpora from documentation data.
    • Re-exported EditorDocs and EditorMetadata types in editor packages.
  • Documentation
    • Updated SPEC, traceability, and current-state docs for the FR-132 picker hardening.
  • Tests
    • Extended picker and corpus-building parity tests for label disambiguation, flat-list rendering, partial categorization, and sparse/no-content docs.

User-reported regression: the docs-site embed's Examples picker showed all
163 cases "duplicated and uncategorised". Root cause: FR-132's tier/rule
joins happen only inside buildExampleCorpus, which a host-supplied
host.examples override bypasses — the docs site hand-maps the engine corpus
(dropping rule/tier), so everything fell into one "Reference · other"
optgroup, and the doc-first-sentence labels are not unique (the pinned
corpus collides in three rule groups even when categorised), so distinct
cases rendered identical labels.

SPEC-first amendment of FR-132 (v2.8, no new IDs):
- Colliding labels within a group are disambiguated with " — <case name>".
- A corpus with no tier/rule membership at all renders as a flat,
  ungrouped list — no fabricated "other" header.
- The corpus derivation is exported for embedders.

Implementation:
- examples.ts: split buildExampleCorpusFromDocs(docs) out of
  buildExampleCorpus — takes the EditorDocs shape, isomorphic to the
  engine get_all_docs() payload, so hosts derive instead of hand-mapping.
- panels.tsx: groupExamples returns a label:null group for group-less
  corpora (rendered without optgroup chrome; partially categorised corpora
  keep "Reference · other"); disambiguatedLabels suffixes per group.
- editor-react + editor-element re-export buildExampleCorpus /
  buildExampleCorpusFromDocs (+ EditorDocs/EditorMetadata types).

Tests red-first (examples-picker.test.tsx): flat degradation, mixed-corpus
"other" retention, collision suffix, per-group disambiguation scoping,
from-docs parity. Traceability FR-132 row updated in the same change.
Gates green (traceability, parity 23/29/34, snapshot); live-verified in the
Pyodide reference host: 163 options, 22 groups, 0 duplicate values, 0
remaining within-group label collisions.

Follow-up (docs-site repo): swap toExampleCases for the exported
buildExampleCorpusFromDocs once a new editor tarball is released, restoring
tiers/rule groups in the embedded picker.

Refs: FR-132, FR-009
Slice: fix-examples-picker-host-corpus

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jul 18, 2026

Copy link
Copy Markdown

Review Change Stack

Walkthrough

The change documents FR-132 in SPEC v2.8, extracts a docs-based example-corpus builder with package re-exports, and updates the Examples picker to disambiguate duplicate labels and render fully ungrouped host corpora as flat lists.

Changes

FR-132 picker hardening

Layer / File(s) Summary
FR-132 presentation contract
docs/SPEC.md, docs/current-state.md, docs/traceability.md
Documents v2.8 label disambiguation, flat fallback rendering, host-corpus handling, and verification coverage.
Docs-based corpus builder and exports
packages/editor-ui/src/session/examples.ts, packages/editor-ui/src/index.ts, packages/editor-react/src/index.ts, packages/editor-element/src/index.ts, packages/editor-ui/test/examples-picker.test.tsx
Adds buildExampleCorpusFromDocs, delegates the existing builder to it, exposes related builders and editor types, and verifies corpus parity and sparse-doc behavior.
Grouped and flat picker rendering
packages/editor-ui/src/components/panels.tsx, packages/editor-ui/test/examples-picker.test.tsx
Supports ungrouped corpora without fabricated optgroups, preserves partial “Reference · other” grouping, and appends case names to duplicate labels within each group.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Host as Host
  participant Builder as buildExampleCorpusFromDocs
  participant Docs as EditorDocs
  participant Panel as ExamplesPanel
  participant Select as HTML select

  Host->>Builder: provide EditorDocs
  Builder->>Docs: read rules, worked_examples, and recipes
  Docs-->>Builder: provide tier and rule associations
  Builder-->>Panel: return ExampleCase[]
  Panel->>Panel: group examples and disambiguate labels
  Panel->>Select: render optgroups or flat options
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: FR-132 v2.8 hardening of the Examples picker for host-supplied corpora.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix-examples-picker-host-corpus

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/editor-ui/test/examples-picker.test.tsx`:
- Around line 132-142: Update both tests in
packages/editor-ui/test/examples-picker.test.tsx at lines 132-142 and 165-177 to
include comments citing FR-132 (v2.8), using the requirement descriptions
provided for the partially categorised corpus and per-group scoping cases.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 5b5baae4-9849-4ee5-920d-cdb87da78cfe

📥 Commits

Reviewing files that changed from the base of the PR and between 21921e2 and be3aef7.

📒 Files selected for processing (9)
  • docs/SPEC.md
  • docs/current-state.md
  • docs/traceability.md
  • packages/editor-element/src/index.ts
  • packages/editor-react/src/index.ts
  • packages/editor-ui/src/components/panels.tsx
  • packages/editor-ui/src/index.ts
  • packages/editor-ui/src/session/examples.ts
  • packages/editor-ui/test/examples-picker.test.tsx

Comment thread packages/editor-ui/test/examples-picker.test.tsx
@codecov

codecov Bot commented Jul 18, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 78.80%. Comparing base (21921e2) to head (908fc1a).

Additional details and impacted files
@@            Coverage Diff             @@
##             main      #19      +/-   ##
==========================================
+ Coverage   78.46%   78.80%   +0.33%     
==========================================
  Files          38       38              
  Lines        2907     2930      +23     
  Branches      464      473       +9     
==========================================
+ Hits         2281     2309      +28     
+ Misses        598      595       -3     
+ Partials       28       26       -2     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

…yload fallbacks

- Add the FR-132 (v2.8) citation comments CodeRabbit flagged on the
  partially-categorised-corpus and per-group-scoping tests.
- Codecov patch gaps: new sparse/malformed-docs test drives the tolerant
  fallback branches in buildExampleCorpusFromDocs (missing curated lists,
  non-list rule refs, non-string param refs, absent corpus) to 100%;
  panels.tsx drops a dead empty-corpus branch (the panel returns null
  before groupExamples runs) and an unreachable `?? 0` on a map key
  populated one loop earlier.

Refs: FR-132
Slice: fix-examples-picker-host-corpus

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
packages/editor-ui/test/examples-picker.test.tsx (2)

185-186: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Cite FR-132 on this test directly.

The enclosing describe includes FR-132, but this individual test does not cite the requirement in its name or comment. Add an inline // FR-132 citation or include it in the test name.

As per coding guidelines: “every implemented requirement must have a test that cites its requirement ID in the test name or a comment.” As per path instructions: “Tests must cite the requirement ID they cover.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/editor-ui/test/examples-picker.test.tsx` around lines 185 - 186, Add
a direct FR-132 citation to the individual test named “derives the same
tier/rule joins as buildExampleCorpus from a bare docs payload,” either in its
test name or as an inline comment, while preserving the existing test behavior.

Sources: Coding guidelines, Path instructions


187-188: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Make the corpus assertion independent.

buildExampleCorpus delegates directly to buildExampleCorpusFromDocs in packages/editor-ui/src/session/examples.ts:69-75, so this equality assertion compares the helper with itself through a wrapper and cannot catch shared regressions. Assert the expected ordering and { name, rule, tier } projections instead.

Proposed test assertion
-    expect(corpus).toEqual(buildExampleCorpus(fakeMetadata));
+    expect(corpus.map(({ name, rule, tier }) => ({ name, rule, tier }))).toEqual([
+      { name: 'Worked1', rule: undefined, tier: 'worked-example' },
+      { name: 'Recipe1', rule: undefined, tier: 'recipe' },
+      { name: 'RefB', rule: 'attr', tier: undefined },
+      { name: 'RefA', rule: 'map', tier: undefined },
+      { name: 'RefC', rule: 'attr', tier: undefined },
+      { name: 'Orphan', rule: undefined, tier: undefined },
+    ]);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/editor-ui/test/examples-picker.test.tsx` around lines 187 - 188,
Make the corpus assertion in the examples picker test independent of
buildExampleCorpus: after calling buildExampleCorpusFromDocs, assert the
expected item ordering and each item’s { name, rule, tier } projection directly.
Do not compare against buildExampleCorpus, which delegates to the same helper
and cannot detect shared regressions.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@packages/editor-ui/test/examples-picker.test.tsx`:
- Around line 185-186: Add a direct FR-132 citation to the individual test named
“derives the same tier/rule joins as buildExampleCorpus from a bare docs
payload,” either in its test name or as an inline comment, while preserving the
existing test behavior.
- Around line 187-188: Make the corpus assertion in the examples picker test
independent of buildExampleCorpus: after calling buildExampleCorpusFromDocs,
assert the expected item ordering and each item’s { name, rule, tier }
projection directly. Do not compare against buildExampleCorpus, which delegates
to the same helper and cannot detect shared regressions.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 9d0341dd-5695-4d32-9899-02f3b622b1ba

📥 Commits

Reviewing files that changed from the base of the PR and between be3aef7 and 908fc1a.

📒 Files selected for processing (2)
  • packages/editor-ui/src/components/panels.tsx
  • packages/editor-ui/test/examples-picker.test.tsx

@Evgenus
Evgenus merged commit b6ff2ce into main Jul 18, 2026
7 checks passed
@Evgenus
Evgenus deleted the fix-examples-picker-host-corpus branch July 18, 2026 22:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant